package com.lagou.edu.factory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanFactory {

    private final static Map<String, Object> BEAN_MAP = new HashMap<>();

    static {
        try (InputStream ras = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml")){
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(ras);
            Element rootElement = document.getRootElement();
            List<Element> beanElements = rootElement.selectNodes("//bean");
            for (Element beanElement : beanElements) {
                BEAN_MAP.put(beanElement.attributeValue("id"),
                        Class.forName(beanElement.attributeValue("class")).newInstance());
            }
            List<Element> propertyElements = rootElement.selectNodes("//bean/property");
            for(Element propertyElement : propertyElements){
                String parentId = propertyElement.getParent().attributeValue("id");
                Object bean = BEAN_MAP.get(parentId);
                Object ref = BEAN_MAP.get(propertyElement.attributeValue("ref"));
                String nameAttr = propertyElement.attributeValue("name");
                for (Method method : bean.getClass().getMethods()) {
                    if(("set" + nameAttr).equals(method.getName())){
                        Parameter[] parameters = method.getParameters();
                        if(parameters != null && parameters.length == 1){
                            ref.getClass().isAssignableFrom(parameters[0].getType());
                            method.invoke(bean, ref);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String id) {
        return BEAN_MAP.get(id);
    }
}
